package com.ftg.learn.mall.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ftg.learn.mall.controller.PmsProductCategoryController;
import com.ftg.learn.mall.dto.PmsProductCategoryParam;
import com.ftg.learn.mall.dto.PmsProductCategoryWithChildrenItem;
import com.ftg.learn.mall.entity.PmsProductCategory;
import com.ftg.learn.mall.mapper.PmsProductCategoryMapper;
import com.ftg.learn.mall.service.IPmsProductCategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 产品分类 服务实现类
 * </p>
 *
 * @author mallCommon
 * @since 2022-04-19
 */
@Service
public class PmsProductCategoryServiceImpl extends ServiceImpl<PmsProductCategoryMapper, PmsProductCategory> implements IPmsProductCategoryService {

    @Resource
    PmsProductCategoryMapper pmsProductCategoryMapper;

    /**
     * 根据id获取父级下子级分类
     * @return
     */
    @Override
    public List<PmsProductCategoryParam> findParentAndChild(Long id){
        return pmsProductCategoryMapper.findParentAndChild(id);
    }

    /**
     * 修改父级状态栏显示
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = SQLException.class)
    public int updateNavStatus(List<Long> ids , Long navStatus) {
        int count = 0;
        for(Long i:ids){
            pmsProductCategoryMapper.updateNavStatus(i,navStatus);
            count++;
        }
        return count;
    }

    /**
     * 修改显示状态
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = SQLException.class)
    public int updateShowStatus(List<Long> ids , Long showStatus) {
        int count = 0;
         for(Long i:ids){
            pmsProductCategoryMapper.updateShowStatus(i,showStatus);
            count++;
        }
        return count;
    }

    /**
     * 查询所有一级产品类型分类及子分类(级联查询)
     * @return
     */
    @Override
    public List<PmsProductCategoryWithChildrenItem> findWithChildren() {
        return pmsProductCategoryMapper.findWithChildren();
    }

    /**
     * 查询所有一级产品类型分类及子分类(递归)
     * @return
     */
    public List<PmsProductCategoryWithChildrenItem> findWithChildrenByRecursion(){
        List<PmsProductCategoryWithChildrenItem> target = new ArrayList<>();
        // 查询出的所有产品类型数据
        List<PmsProductCategoryWithChildrenItem> list = pmsProductCategoryMapper.findAllProductCategory();
        createTree(target,list,0L);
        return target;
    }


    /**
     * 按树形结构列出所有产品类型
     * @param target  目标数据
     * @param data    源数据
     * @param pid   数据主键
     */
    public void createTree(List<PmsProductCategoryWithChildrenItem> target,
                           List<PmsProductCategoryWithChildrenItem> data,
                           Long pid){
        if (findSon(data,pid)){
            data.forEach(x -> {
                if (x.getParentId().equals(pid)){
                    PmsProductCategoryWithChildrenItem parent = findParent(data,x);
                    if (parent == null){
                        target.add(x);
                    }else {
                        parent.getChildren().add(x);
                    }
                    createTree(target,data,x.getProductCategoryId());
                }
            });
        }
    }

    /**
     * 找当前项的子项,只要有一个子项就返回true，无子项返回false。
     * @param data
     * @param pid
     */
    public boolean findSon(List<PmsProductCategoryWithChildrenItem> data,
                        Long pid){
        return data.stream().anyMatch(x -> x.getParentId().equals(pid));
    }


    /**
     * 判断 son 在 data 中是否存在父级元素。
     * @param data
     * @param son
     * @return
     */
    public PmsProductCategoryWithChildrenItem findParent(List<PmsProductCategoryWithChildrenItem> data,
                                                         PmsProductCategoryWithChildrenItem son){
        for (PmsProductCategoryWithChildrenItem productCategoryWithChildrenItem : data){
            if (productCategoryWithChildrenItem.getProductCategoryId().equals(son.getParentId())){
                return productCategoryWithChildrenItem;
            } else {
                findParent(productCategoryWithChildrenItem.getChildren(),son);
            }
        }
        return null;
    }


}
